package main

import (
	"fmt"
	"reflect"
)

type Foo struct {
	Name string
	Age  int
}

func main() {
	foo := Foo{"caixisheng", 18}

	// type
	typ := reflect.TypeOf(foo)
	fmt.Println(typ.Name(), " |", typ.String())

	// field
	for i := 0; i < typ.NumField(); i++ {
		field := typ.Field(i)
		fmt.Printf("%s type is :%s\n", field.Name, field.Type)
	}
	age, _ := typ.FieldByName("Age")
	fmt.Println(age)

	// value
	v := reflect.ValueOf(foo)
	fmt.Println("ValueOf 拿到的值不可以直接改变", v.CanSet())

	//relect.Value是字符s的一个反射对象，是不能直接对它进行赋值操作的。 要对s进行赋值，需要先拿到s的指针对应的reflect.Value,然后通过Value.Elem()再对应到s，然后才能赋值操作。 这个地方是相当拗口啊:(
	var i int = 123
	fv := reflect.ValueOf(i)
	fe := reflect.ValueOf(&i).Elem()
	fmt.Println(fe)
	fmt.Println(fv)
	fmt.Println(fv == fe)

	fe.SetInt(43)
	fmt.Println(i)

}
